package unrn.isiii.service.ws;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.inject.Singleton;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import unrn.isiii.service.ws.Message.MessageDecoder;
import unrn.isiii.service.ws.Message.MessageEncoder;


@ServerEndpoint(value = "/publico", encoders = { MessageEncoder.class }, decoders = { MessageDecoder.class })
@Singleton
public class PublicoEndPoint implements Serializable {

	/** log */
	private static final Logger logger = Logger.getLogger("PublicoEndPoint");

	/**
	 * Message receiver method
	 * 
	 * @param message
	 * @return
	 */
	static Set<Session> sessions = Collections
			.synchronizedSet(new HashSet<Session>());

	public static synchronized void send(Message msg) {
		try {

			for (Session session : sessions) {

				if (session.isOpen()) {
					session.getAsyncRemote().sendObject(msg);
					logger.log(Level.INFO, "Canal Publico - Send: {0}",
							msg.getMessage());

				}
			}
		} catch (Exception e) {
			logger.log(Level.INFO, "WS publico Error: {0}", e.toString());
		}
	}

	@OnMessage
	public void message(final Session session, Message msg) {
		logger.log(Level.INFO, "Canal Publico: - {0}", msg.getMessage());
	}

	@OnOpen
	public synchronized void onOpen(Session session) {
		logger.log(Level.INFO, "Session ID : " + session.getId());
		sessions.add(session);
		
		send(new Message("chichi", "ok"));
	}

	@OnClose
	public synchronized void closedConnection(Session session) {
		sessions.remove(session);
		logger.log(Level.INFO, "Canal Publico Closed.");
	}

	@OnError
	public synchronized void error(Session session, Throwable t) {
		sessions.remove(session);
		logger.log(Level.INFO, t.toString());
		logger.log(Level.INFO, "Canal Publico: Connection error.");
	}

	public static Set<Session> getSessions() {
		return sessions;
	}

	public static void setSessions(Set<Session> sessions) {
		PublicoEndPoint.sessions = sessions;
	}
}
